using MultiAgentsClient.Service.WorkflowEngine;
using MultiAgentsClient.Service.WorkflowEngine.BaseNodes;

namespace MultiAgentsServer.Scripts.Shared.WorkflowEngine.BuiltInNodes;

[NodeGraphPortDef(1, 2)]
public class IfElseNode : BaseNode
{
    public enum ConditionBinder
    {
        And = 0,
        Or = 1,
    }

    public enum Comparitor
    {
        Equal = 0,
        NotEqual = 1,
        Larger = 2,
        Smaller = 3,
        Include = 4,
        NotInclude = 5,
        IsNull = 6,
    }

    public class Condition
    {
        public string Variable { get; set; }
        public Comparitor Comparitor { get; set; }
        public string Value { get; set; }

        public bool Evaluate()
        {
            switch (Comparitor)
            {
                case Comparitor.Equal:
                    return Variable == Value;
                case Comparitor.NotEqual:
                    return Variable != Value;
                case Comparitor.Larger:
                    return false;
                case Comparitor.Smaller:
                    return false;
                case Comparitor.Include:
                    return Variable.Contains(Value);
                case Comparitor.NotInclude:
                    return Variable.Contains(Value) == false;
                case Comparitor.IsNull:
                    return Variable.IsNullOrEmpty();
            }
            throw new Exception("Should not happen.");
        }
    }

    [NodeGraphParam] public ConditionBinder ConditionBinderEnum = ConditionBinder.And;
    [NodeGraphParam] public List<Condition> Conditions = [];
    private List<Condition> ConditionsRuntime => InsertVariable(Conditions);

    public override async Task<NodeOutcome> ExecuteNodeAsync()
    {
        var finalResult = false;

        if (ConditionBinderEnum == ConditionBinder.And)
        {
            foreach (var condition in ConditionsRuntime)
            {
                var evalResult = condition.Evaluate();
                if (evalResult == false)
                {
                    finalResult = false;
                    break;
                }
                else
                {
                    finalResult = true;
                }
            }
        }
        else if (ConditionBinderEnum == ConditionBinder.Or)
        {
            foreach (var condition in ConditionsRuntime)
            {
                var evalResult = condition.Evaluate();
                if (evalResult == true)
                {
                    finalResult = true;
                    break;
                }
            }
        }
        else
        {
            throw new NotImplementedException();
        }

        if (finalResult)
        {
            return await Task.FromResult(new NodeOutcome(NodeOutcomeStatus.Success, 0));
        }
        else
        {
            return await Task.FromResult(new NodeOutcome(NodeOutcomeStatus.Success, 1));
        }
    }

    public override void Dispose()
    {
    }
}
